package com.jinzhi.jzweb.service.impl;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.word.WordExportUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jinzhi.common.service.DictService;
import com.jinzhi.common.utils.Result;
import com.jinzhi.common.utils.StringUtil;
import com.jinzhi.jzweb.dao.JazSignupGroupDao;
import com.jinzhi.jzweb.dao.JazSignupItemDao;
import com.jinzhi.jzweb.domain.JazSignupGroupDO;
import com.jinzhi.jzweb.domain.JazSignupItemDO;
import com.jinzhi.jzweb.domain.JazSignupUserDO;
import com.jinzhi.jzweb.domain.param.SignUserQuery;
import com.jinzhi.jzweb.domain.vo.userAunt.JazSignupUserTeamExcelVO;
import com.jinzhi.jzweb.service.JazSignupUserService;
import com.jinzhi.jzweb.utils.ExcelUtil;
import com.jinzhi.jzweb.utils.HttpClientUtil;
import com.jinzhi.jzweb.utils.ZipUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;

import com.jinzhi.jzweb.dao.JazSignupTeamDao;
import com.jinzhi.jzweb.domain.JazSignupTeamDO;
import com.jinzhi.jzweb.service.JazSignupTeamService;
import com.jinzhi.common.base.CoreServiceImpl;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.*;

/**
 *
 * <pre>
 * 报名队伍表
 * </pre>
 * <small> 2024-09-05 15:21:58 | Long</small>
 */
@Service
public class JazSignupTeamServiceImpl extends CoreServiceImpl<JazSignupTeamDao, JazSignupTeamDO> implements JazSignupTeamService {

    @Resource
    private JazSignupItemDao jazSignupItemDao;

    @Resource
    private JazSignupGroupDao jazSignupGroupDao;

    @Resource
    private JazSignupUserService jazSignupUserService;

    @Resource
    private JazSignupTeamDao jazSignupTeamDao;

    @Resource
    private DictService dictService;

    /**
     * 分页查询报名队伍表
     *
     * @param signUserQuery
     * @return
     */
    @Override
    public Page<JazSignupTeamDO> selectTeamPage(SignUserQuery signUserQuery) {
        Page<JazSignupTeamDO> page = new Page<>(signUserQuery.getCurr(), signUserQuery.getPageSize());
        // 查询列表数据
        EntityWrapper<JazSignupTeamDO> wrapper = new EntityWrapper<>();
        wrapper.eq(signUserQuery.getGroupId()!=null,"group_id", signUserQuery.getGroupId());
        wrapper.eq(signUserQuery.getItemId()!=null,"item_id", signUserQuery.getItemId());
        wrapper.like(StringUtil.notEmpty(signUserQuery.getTeamName()),"name", signUserQuery.getTeamName());
        wrapper.eq("result", 1);

        Page<JazSignupTeamDO> userDOPage = this.selectPage(page, wrapper);

        // 组装数据
        userDOPage.getRecords().forEach(item -> {
            extractedName(item);
        });

        List<JazSignupTeamDO> records = userDOPage.getRecords();
        // 判断是否存在领队信息，不存在剔除队伍信息
        // 遍历队伍记录，检查领队信息
        records.removeIf(i -> {
            // 查询领队信息
            List<JazSignupUserDO> list = jazSignupUserService.selectList(
                    new EntityWrapper<JazSignupUserDO>()
                            .eq("team_id", i.getId())
                            .eq("group_id", i.getGroupId())
                            .eq("type", 1)
                            .eq("result", 1)
            );

            // 如果领队信息列表不为空，则移除当前队伍信息
            return list != null && list.size()<=0;
        });


        userDOPage.setRecords(records);
        userDOPage.setTotal(records.size());


        return userDOPage;
    }



    /**
     * 封装 组别名称、参赛名称、队伍名称
     * @param item
     */
    private void extractedName(JazSignupTeamDO item) {
        // 查询组别名称
        JazSignupGroupDO jazSignupGroupDO = jazSignupGroupDao.selectById(item.getGroupId());
        if (jazSignupGroupDO != null){
            item.setGroupName(jazSignupGroupDO.getName());
        }
        // 查询参赛名称
        JazSignupItemDO jazSignupItemDO = jazSignupItemDao.selectById(item.getItemId());
        if (jazSignupItemDO != null){
            item.setItemName(jazSignupItemDO.getName());
        }
        // 查询所属队伍
//        JazSignupTeamDO jazSignupTeamDO = jazSignupTeamService.selectById(item.getTeamId());
//        if (jazSignupTeamDO != null){
//            item.setTeamName(jazSignupTeamDO.getName());
//        }
    }

    /**
     * 封装 组别名称、参赛名称、队伍名称
     * @param item
     */
    private void extractedName1(JazSignupUserDO item) {
        // 查询组别名称
        JazSignupGroupDO jazSignupGroupDO = jazSignupGroupDao.selectById(item.getGroupId());
        if (jazSignupGroupDO != null){
            item.setGroupName(jazSignupGroupDO.getName());
        }
        // 查询参赛名称
        JazSignupItemDO jazSignupItemDO = jazSignupItemDao.selectById(item.getItemId());
        if (jazSignupItemDO != null){
            item.setItemName(jazSignupItemDO.getName());
        }
        // 查询所属队伍
//        JazSignupTeamDO jazSignupTeamDO = jazSignupTeamService.selectById(item.getTeamId());
//        if (jazSignupTeamDO != null){
//            item.setTeamName(jazSignupTeamDO.getName());
//        }
    }


    /**
     * 根据id查询报名队伍表
     *
     * @param id
     * @return
     */
    @Override
    public Result<JazSignupTeamDO> getById(Long id) {
        JazSignupTeamDO jazSignupTeamDO = this.selectById(id);
        if (jazSignupTeamDO == null){
            return Result.fail("未查询到数据");
        }

        // 设置组别名称
        extractedName(jazSignupTeamDO);

        // 查询领队信息
        JazSignupUserDO jazSignupUserDO = jazSignupUserService.selectOne(
                new EntityWrapper<JazSignupUserDO>().eq("team_id", id)
                        .eq("group_id", jazSignupTeamDO.getGroupId())
                        .eq("type",1).eq("result",1));
        if (jazSignupUserDO == null){
            return Result.fail("暂无领队信息,请添加领队信息");
        }
        jazSignupTeamDO.setJazSignupUserDO(jazSignupUserDO);

        // 查询项目类型
        List<JazSignupItemDO> itemList = jazSignupItemDao.selectList(new EntityWrapper<JazSignupItemDO>()
                .eq("group_id", jazSignupTeamDO.getGroupId()));
        // 查询项目类型
        Map<String, List<JazSignupUserDO>> map = new HashMap<>();
        itemList.forEach(item -> {
            map.put(item.getName(),new ArrayList<JazSignupUserDO>());
        });

        // 根据队伍查询出所有的选手信息
        List<JazSignupUserDO> jazSignupUserDOList =jazSignupUserService.selectList(new EntityWrapper<JazSignupUserDO>()
                .eq("team_id",id).eq("type",2)
                .eq("group_id",jazSignupTeamDO.getGroupId())
                .eq("result",1));
        jazSignupUserDOList.forEach(item -> {

            JazSignupItemDO jazSignupItemDO = jazSignupItemDao.selectById(item.getItemId());
            if (jazSignupItemDO != null){
                item.setItemName(jazSignupItemDO.getName());
            }
            List<JazSignupUserDO> list=map.get(item.getItemName());
            list.add(item);
            map.put(item.getItemName(),list);
        });

        jazSignupTeamDO.setMap(map);

        return Result.ok(jazSignupTeamDO);
    }





    /**
     * 生成报名表
     *
     * @param response
     * @param jazSignupUserDO
     */
    @Override
    public void documentWord(HttpServletResponse response, JazSignupUserDO jazSignupUserDO) throws Exception {
        JazSignupUserDO jazSignupUserDO1 = jazSignupUserService.selectById(jazSignupUserDO.getId());
        extractedName1(jazSignupUserDO1);
        //导出组装数据
        Map<String,Object> params =new HashMap<>();
        params.put("teamName",jazSignupUserDO1.getTeamName());
        params.put("itemName",jazSignupUserDO1.getItemName());
        params.put("name",jazSignupUserDO1.getName());
        if (jazSignupUserDO1.getSex() == 1){
            params.put("sex","男");
        }else if (jazSignupUserDO1.getSex() == 2){
            params.put("sex","女");
        }else if (jazSignupUserDO1.getSex() == 0){
            params.put("sex","未知");
        }
        params.put("nation",jazSignupUserDO1.getNation());
        params.put("birthday",jazSignupUserDO1.getBirthday());
        params.put("politics",jazSignupUserDO1.getPolitics());
        params.put("standard",jazSignupUserDO1.getStandard());
        params.put("identityCard",jazSignupUserDO1.getIdentityCard());
        params.put("working",jazSignupUserDO1.getWorking());
        params.put("orgName",jazSignupUserDO1.getOrgName()+"     "+jazSignupUserDO1.getPhone());
        params.put("brief",jazSignupUserDO1.getBrief());
        params.put("honor",jazSignupUserDO1.getHonor());
        params.put("skill",jazSignupUserDO1.getSkill());
        if (StringUtil.notEmpty(jazSignupUserDO1.getUserImg())){
            String[] split = jazSignupUserDO1.getUserImg().split(",");
//            List<ImageEntity> imageEntities = initImageData(split[0]);
            ImageEntity item = new ImageEntity();
            item.setWidth(50);
            item.setHeight(70);
            item.setData(HttpClientUtil.getImageFromNetByUrl(split[0]));
            item.setType(ImageEntity.Data);
            params.put("userImg",item);
        }


        XWPFDocument word = WordExportUtil.exportWord07(templateFile().getPath(),params);
        response.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode("选手登记表.docx", "UTF-8"));
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        word.write(response.getOutputStream());
    }


    /**
     * 报名队伍导出
     * @param response
     * @param signUserQuery
     */
    @Override
    public void downloadImportTemplate(HttpServletResponse response, SignUserQuery signUserQuery) {
        //查询磁盘存储路径
        Map<String, byte[]> fileBufMap=new HashMap<String, byte[]>();
        if (null==signUserQuery.getIds()||signUserQuery.getIds().length ==0){
         List<JazSignupTeamDO> jazSignupTeamDOList=  jazSignupTeamDao.selectList(new EntityWrapper<JazSignupTeamDO>()
                 .eq("result",1));
         // 判断是否有数据
            if (jazSignupTeamDOList.size()<=0){
//                return Result.fail("暂无队伍信息");
            }

            for (JazSignupTeamDO t:  jazSignupTeamDOList) {

                JazSignupTeamDO jazSignupUserDO1=this.getById(t.getId()).getData();
                fileBufMap= extracted(jazSignupUserDO1.getName(),jazSignupUserDO1, fileBufMap);
            }
        }else{
            for (int i = 0; i < signUserQuery.getIds().length; i++) {
                JazSignupTeamDO jazSignupUserDO1=this.getById(signUserQuery.getIds()[i]).getData();
                fileBufMap= extracted(jazSignupUserDO1.getName(),jazSignupUserDO1, fileBufMap);
            }
        }
        try {
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            String  fileName =  URLEncoder.encode("队伍信息导出.zip", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION,  "attachment; filename*=" + fileName);
            // 压缩包导出
            ZipUtils.downloadZipForByteMore(response.getOutputStream(), fileBufMap);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }




    private Map<String, byte[]> extracted(String name, JazSignupTeamDO jazSignupUserDO1, Map<String, byte[]> fileBufMap) {
        List<JazSignupUserTeamExcelVO> list=new ArrayList<>();
        //领队
        JazSignupUserDO item1= jazSignupUserDO1.getJazSignupUserDO();
        JazSignupUserTeamExcelVO jaz1=new JazSignupUserTeamExcelVO();
        // 数据转换
        if (item1.getType()==1){
            jaz1.setType("领队");
        }else if (item1.getType()==2){
            jaz1.setType("参赛选手");
        }
        jaz1.setPhone(item1.getPhone());
        jaz1.setName(item1.getName());

        list.add(jaz1);
        //选手循环获取
        Map<String, List<JazSignupUserDO>> maps= jazSignupUserDO1.getMap();
        for(List<JazSignupUserDO> listJaz:maps.values()){
                    for (JazSignupUserDO item :listJaz) {
                        JazSignupUserTeamExcelVO jaz=new JazSignupUserTeamExcelVO();
                        try {
                            // 数据转换
                            if (item.getType()==1){
                                jaz.setType("领队");
                            }else if (item.getType()==2){
                                jaz.setType("参赛选手");
                            }
                            // 性别转换
                            if (item.getSex()==1){
                                jaz.setSex("男");
                            }else if (item.getSex()==2){
                                jaz.setSex("女");
                            }else {
                                jaz.setSex("未知");
                            }
                            // 查询参赛名称
                            JazSignupItemDO jazSignupItemDO = jazSignupItemDao.selectById(item.getItemId());
                            if (jazSignupItemDO != null){
                                jaz.setItemName(jazSignupItemDO.getName());
                            }
                            jaz.setName(item.getName());
                            jaz.setIdentityCard(item.getIdentityCard());
                            jaz.setNation(item.getNation());
                            jaz.setPolitics(item.getPolitics());
                            jaz.setStandard(item.getStandard());
                            jaz.setWorking(item.getWorking());
                            jaz.setOrgName(item.getOrgName());
                            jaz.setItemName(item.getItemName());
                            jaz.setPhone(item.getPhone());
                            jaz.setSize(item.getSize());

                            list.add(jaz);
                            fileBufMap.put(name+"/"+item.getItemName()+"/"+item.getName()+"-"+item.getPhone()+".doc", getByte(item));
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
        }
        //附件
        String applyform= jazSignupUserDO1.getJazSignupUserDO().getApplyForm();
        fileBufMap.put(name+"/附件"+applyform.substring(applyform.lastIndexOf(".")), HttpClientUtil.getImageFromNetByUrl(applyform));
        //excel

        try {
            byte[] excel = ExcelUtil.getExportExcelBytes(list, "汇总表", "汇总表", JazSignupUserTeamExcelVO.class, "", null);
            fileBufMap.put(name+"/登记汇总表.xls",excel);
        }catch (Exception e){
            throw new RuntimeException(e);
        }

       return fileBufMap;
    }

    private byte[] getByte(JazSignupUserDO jazSignupUserDO ) throws Exception {
        //第一个word
        extractedName1(jazSignupUserDO);
        //导出组装数据
        Map<String,Object> params =new HashMap<>();
        params.put("teamName",jazSignupUserDO.getTeamName());
        params.put("itemName",jazSignupUserDO.getItemName());
        params.put("name",jazSignupUserDO.getName());
        if (jazSignupUserDO.getSex() == 1){
            params.put("sex","男");
        }else if (jazSignupUserDO.getSex() == 2){
            params.put("sex","女");
        }
        params.put("nation",jazSignupUserDO.getNation());
        params.put("birthday",jazSignupUserDO.getBirthday());
        params.put("politics",jazSignupUserDO.getPolitics());
        params.put("standard",jazSignupUserDO.getStandard());
        params.put("identityCard",jazSignupUserDO.getIdentityCard());
        params.put("working",jazSignupUserDO.getWorking());
        params.put("orgName",jazSignupUserDO.getOrgName()+"     "+jazSignupUserDO.getPhone());
        params.put("brief",jazSignupUserDO.getBrief());
        params.put("honor",jazSignupUserDO.getHonor());
        params.put("skill",jazSignupUserDO.getSkill());
        if (StringUtil.notEmpty(jazSignupUserDO.getUserImg())){
            String[] split = jazSignupUserDO.getUserImg().split(",");
//            List<ImageEntity> imageEntities = initImageData(split[0]);
            ImageEntity item = new ImageEntity();
            item.setWidth(50);
            item.setHeight(70);
            item.setData(HttpClientUtil.getImageFromNetByUrl(split[0]));
            item.setType(ImageEntity.Data);
            params.put("userImg",item);
        }
            XWPFDocument word = WordExportUtil.exportWord07(templateFile().getPath(), params);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            word.write(bos);
            return bos.toByteArray();
    }



    //获取docx文件位置
    private File templateFile() throws IOException {

        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("signTemplate.docx");
        if (inputStream == null) {
            throw new RuntimeException("Template file not found in resources");
        }

        // 将输入流转换为临时文件
        File tempFile = null;
        try {
            tempFile = File.createTempFile("template", ".docx");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        tempFile.deleteOnExit(); // 在JVM退出时删除临时文件
        Files.copy(inputStream, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        return tempFile;
    }






}
